package com.qust.EnDecryption.handle;

import com.alibaba.fastjson2.JSONObject;
import com.qust.agreement.Enums.InstructionEnum;
import com.qust.agreement.Message;
import com.qust.agreement.message.ResponseMessage;
import com.qust.agreement.result.Result;
import com.qust.encryptionAndDecryption.IEnDecryption;
import com.qust.exception.NoSuchEnDecryptionException;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.extern.log4j.Log4j2;

import java.util.Map;

/**
 * 执行加解密的handle<br/>
 * 用来处理Message.EnDecryptionContext<br/>
 * Message.EnDecryptionContext{<br/>
 * <p>&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp code:加密算法编号</p>
 * <p>&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp context: 加解密原文</p>
 * }<br/>
 */
@Log4j2
public class EnDecryptionHandle extends ChannelInboundHandlerAdapter {
    private Map<Integer, IEnDecryption> map; // 加解密算法与编号之间的映射

    public EnDecryptionHandle(Map<Integer, IEnDecryption> map) {
        this.map = map;
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info("{}连接", ctx.channel().remoteAddress());
        super.channelActive(ctx);
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        Message message = (Message) msg;
        if (message.getInstruction() == InstructionEnum.decryption.getCode() || message.getInstruction() == InstructionEnum.encryption.getCode()) {
            log.debug("转换对象");
            JSONObject jsonObject = (JSONObject) message.getContext();
            Message.EnDecryptionContext enDecryptionContext = jsonObject.to(Message.EnDecryptionContext.class);
            log.debug("获取加解密算法");
            IEnDecryption iEnDecryption = map.get(enDecryptionContext.getCode());
            if (iEnDecryption == null) {
                throw new NoSuchEnDecryptionException();
            }
            log.debug("执行");
            String execution = execution(message.getInstruction(), enDecryptionContext.getContext(), iEnDecryption);
            ctx.channel().writeAndFlush(new ResponseMessage(Result.success(execution)));
        } else {
            super.channelRead(ctx, msg);
        }
    }

    /**
     * 执行指令
     *
     * @param instruction  指令,加密(0)或者解密(1)
     * @param context      加解密的数据
     * @param enDecryption 加解密算法
     * @return 执行完毕的数据
     */
    private String execution(int instruction, String context, IEnDecryption enDecryption) {
        if (instruction == InstructionEnum.decryption.getCode()) {
            return enDecryption.decryption(context);
        } else if (instruction == InstructionEnum.encryption.getCode()) {
            return enDecryption.encryption(context);
        } else {
            return null;
        }
    }


}
